package com.mingqijia.gassafety.webserver.service.workorder.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.basic.exception.BizException;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.entity.redis.LatestLog;
import com.mingqijia.gassafety.db.entity.vo.DeviceStateVO;
import com.mingqijia.gassafety.db.entity.vo.HistoryAlarmVo;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.shared.constant.AppealStateEnum;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.utils.TimeUtil;
import com.mingqijia.gassafety.shared.utils.commonUtils.BeanConvertUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.DateUtils;
import com.mingqijia.gassafety.webserver.constant.DeviceConstant;
import com.mingqijia.gassafety.webserver.request.inner.ReportRequest;
import com.mingqijia.gassafety.webserver.response.AlarmDataResponse;
import com.mingqijia.gassafety.webserver.response.ContactsResponse;
import com.mingqijia.gassafety.webserver.response.StrategyReportResponse;
import com.mingqijia.gassafety.webserver.response.inner.IotskDtuResponse;
import com.mingqijia.gassafety.webserver.response.client.H5LogRes;
import com.mingqijia.gassafety.webserver.response.sk.AlarmSupplierListVo;
import com.mingqijia.gassafety.webserver.response.workorder.asst.ConsumerH5Response;
import com.mingqijia.gassafety.webserver.response.workorder.asst.DetectorInfoH5Response;
import com.mingqijia.gassafety.webserver.response.workorder.asst.DtuInfoH5Response;
import com.mingqijia.gassafety.webserver.service.BusinessNoticeService;
import com.mingqijia.gassafety.webserver.service.ContactsService;
import com.mingqijia.gassafety.webserver.service.EquipmentManufacturerService;
import com.mingqijia.gassafety.webserver.service.LatestLogService;
import com.mingqijia.gassafety.webserver.service.impl.EquipmentServiceImpl;
import com.mingqijia.gassafety.webserver.service.workorder.H5Service;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName H5ServiceImpl.java
 * @Description
 * @createTime 2022年09月22日
 */
@Slf4j
@Service
public class H5ServiceImpl implements H5Service {


    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    ContactsService contactsService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    DtuMapper dtuMapper;
    @Autowired
    DeviceStateMapper deviceStateMapper;
    @Autowired
    EquipmentServiceImpl  equipmentService;
    @Autowired
    DtuBindingOrderMapper dtuBindingOrderMapper;
    @Autowired
    RunningStrategyReportMapper reportMapper;
    @Autowired
    HistoryAlarmMapper alarmMapper;
    @Autowired
    AppealLogMapper appealLogMapper;
    @Autowired
    BusinessNoticeService noticeService;
    @Autowired
    ConsumerServiceInfoMapper consumerServiceInfoMapper;
    @Autowired
    RunningReportMapper runningReportMapper;
    @Autowired
    RunningReportDataMapper runningReportDataMapper;

    @Autowired
    LatestLogService latestLogService;

    @Autowired
    EquipmentManufacturerService equipmentManufacturerService;

    /**
     * 根据imei查询设备信息
     * @param imei
     * @return
     */
    @Override
    public DtuInfoH5Response equipmentInfo(String imei) {
        DtuInfoH5Response dtuInfoH5Response = new DtuInfoH5Response();
        Dtu dtu = dtuMapper.selectByImei(imei, "");
        if (dtu==null) throw new BizException("当前imei号未匹配到数据");
        BeanUtils.copyProperties(dtu,dtuInfoH5Response);
        Consumer consumer = consumerMapper.selectSubsCodeByConsumerId(dtu.getConsumerId());
        if (consumer!=null) dtuInfoH5Response.setSubsCode(consumer.getSubsCode());
        DeviceStateVO deviceStateByImei = deviceStateMapper.getDeviceStateByImei(imei,dtu.getSpId());
        if (deviceStateByImei!=null){
            dtuInfoH5Response.setSignal(deviceStateByImei.getSignal()==null?0:deviceStateByImei.getSignal());
            dtuInfoH5Response.setEquipmentStatus(deviceStateByImei.getEquipmentStatus());
            if (!StringUtils.isEmpty(deviceStateByImei.getEquipmentStatusInfo())){
                if (deviceStateByImei.getEquipmentStatusInfo().equals("设备离线（通讯不成功）")){
                    dtuInfoH5Response.setEquipmentStatus(5);
                }else if( DeviceConstant.DETECTOR_STATUS_32_INFO.equals(deviceStateByImei.getEquipmentStatusInfo()) ){
                    dtuInfoH5Response.setEquipmentStatus(DeviceConstant.DEVICE_STATUS_6);
                }
            }
        }
        List<Dtu> dtus = dtuMapper.selectLoop(imei);
        List<String> query = equipmentService.getQueryParams();
        List<Map<String, String>> customerCode = equipmentService.dictMap(null, query, null);
        String[] split = dtuInfoH5Response.getDetectionType().split(";");
        String detectionType="";
        if (split.length>=1){
            for (String s : split) {
                detectionType = equipmentService.getStringValue(customerCode,
                        s, query.get(4), "value", "alias")+"、"+detectionType;
            }
            if (detectionType.endsWith("、")) detectionType=detectionType.substring(0,detectionType.length()-1);
        }
        dtuInfoH5Response.setDetectionType(detectionType);
        Map<String, AlarmSupplierListVo>  map = equipmentManufacturerService.queryMap();
        if (MapUtils.isNotEmpty(map) && map.containsKey(dtuInfoH5Response.getEquipmentManufacturer())) {
            dtuInfoH5Response.setEquipmentManufacturer(map.get(dtuInfoH5Response.getEquipmentManufacturer()).getMsName());
        }
//        dtuInfoH5Response.setEquipmentManufacturer(equipmentService.getStringValue(customerCode,
//                dtuInfoH5Response.getEquipmentManufacturer(), query.get(0), "value", "alias"));
        if (EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(dtuInfoH5Response.getEquipmentType())){
            dtuInfoH5Response.setEquipmentTypeCode(1);
        }else {
            dtuInfoH5Response.setEquipmentTypeCode(0);
        }
        //添加设备类型标识
        dtuInfoH5Response.setEquipmentTypeFlag(dtuInfoH5Response.getEquipmentType());
        dtuInfoH5Response.setEquipmentType(equipmentService.getStringValue(customerCode,
                dtuInfoH5Response.getEquipmentType(), query.get(1), "value", "alias"));
        dtuInfoH5Response.setLoopAmount(CollectionUtil.isEmpty(dtus)?0:dtus.size()-1);
        dtuInfoH5Response.setExpirationType(0);
        if (StringUtils.isEmpty(dtu.getExpirationTime())){
            dtuInfoH5Response.setExpirationType(0);
        }else {
            try {
                DateTime expirationTime = DateUtil.parse(dtu.getExpirationTime());
                long between = DateUtil.between(new Date(), expirationTime, DateUnit.HOUR, false);
                if (between <0){
                    dtuInfoH5Response.setExpirationType(2);
                }else if (between <= 60*24){
                    dtuInfoH5Response.setExpirationType(1);
                }
            } catch (Exception e) {
                log.info("日期解析错误", e.getMessage());
                dtuInfoH5Response.setExpirationType(3);
            }
        }
        BusinessNotice notice = noticeService.getByCode("h5_service_state", dtus.get(0).getSpId());
        if (notice != null &&  "ON".equals(notice.getParamValue())){
            dtuInfoH5Response.setExpirationDisplay(1);
        }else {
            dtuInfoH5Response.setExpirationDisplay(0);
        }
        // 服务信息
        QueryWrapper<ConsumerServiceInfo> serviceInfoWrapper = new QueryWrapper<>();
        serviceInfoWrapper.lambda().eq(ConsumerServiceInfo::getSpId, dtu.getSpId())
                .eq(ConsumerServiceInfo::getIsDeleted, 0)
                .eq(ConsumerServiceInfo::getImei, org.apache.commons.lang3.StringUtils.substringBefore(dtu.getIMEI(), "-"));
        List<ConsumerServiceInfo> consumerServiceInfoList = consumerServiceInfoMapper.selectList(serviceInfoWrapper);
        Long today = DateUtils.today().getTime();
        if (CollectionUtil.isNotEmpty(consumerServiceInfoList)) {
            ConsumerServiceInfo serviceInfo = consumerServiceInfoList.get(0);
            if (today <= serviceInfo.getEndDate().getTime() && serviceInfo.getEndDate().getTime() - today <= 30*24*60*60*1000L) {
                dtuInfoH5Response.setServiceStatus(1);
            } else if (today > serviceInfo.getEndDate().getTime()) {
                dtuInfoH5Response.setServiceStatus(2);
            } else {
                dtuInfoH5Response.setServiceStatus(0);
            }
        }
        //运行报告配置
        Integer runningReportShow = null;
        BusinessNotice runningReportNotice = noticeService.getByCode("h5_running_record", dtu.getSpId());
        if (runningReportNotice != null &&  "ON".equals(runningReportNotice.getParamValue())){
            runningReportShow = 0;
        }else {
            runningReportShow = 1;
        }
        dtuInfoH5Response.setRunningReportShow(runningReportShow);
        if ( 1 == dtuInfoH5Response.getEquipmentTypeCode() ){
            List<DetectorInfoH5Response> detectorDeviceList = new ArrayList<>();
            DetectorInfoH5Response detectorInfoH5Response;
            for (Dtu cDtu:dtus) {
                if (!EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode().equals(cDtu.getEquipmentType())){
                    continue;
                }
                LatestLog latestLog = latestLogService.get(cDtu.getIMEI(), cDtu.getSpId());
                detectorInfoH5Response = new DetectorInfoH5Response();
                detectorInfoH5Response.setImei(cDtu.getIMEI());
                detectorInfoH5Response.setEquipmentType(cDtu.getEquipmentType());
                detectorInfoH5Response.setEquipmentTypeName(EquipmentType.POINT_TYPE_GAS_DETECTOR.getName());
                if( DeviceConstant.DETECTOR_STATUS_32_INFO.equals(latestLog.getEquipmentStatusInfo()) ){
                    detectorInfoH5Response.setEquipmentStatus(DeviceConstant.DEVICE_STATUS_6);
                }else{
                    detectorInfoH5Response.setEquipmentStatus(latestLog.getEquipmentStatus());
                }
                detectorInfoH5Response.setEquipmentStatusInfo(latestLog.getEquipmentStatusInfo());
                detectorInfoH5Response.setInstallationPosition(cDtu.getInstallationPosition());
                detectorDeviceList.add(detectorInfoH5Response);
            }
            dtuInfoH5Response.setDetectorDeviceList(detectorDeviceList);
        }
        log.info("查询设备详情：{}", dtuInfoH5Response);
        return dtuInfoH5Response;
    }

    /**
     * 根据id查询客户信息
     *
     * @param id
     * @return
     */
    @Override
    public ConsumerH5Response consumerInfo(String id) {
        ConsumerH5Response consumerH5Response = new ConsumerH5Response();
        QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or().eq(Consumer::getIsDeleted, 0)
                .eq(Consumer::getId, id);
        List<Consumer> consumers = consumerMapper.selectList(queryWrapper);
        if (!CollectionUtil.isEmpty(consumers)) {
            Consumer consumer = consumers.get(0);
            BeanUtils.copyProperties(consumer, consumerH5Response);
        }
        //获取联系人列表
        QueryWrapper<Contacts> contactsWrapper = new QueryWrapper<>();
        contactsWrapper.lambda().eq( Contacts::getConsumerId,id )
                .eq( Contacts::getIsDeleted, Constants.IS_DELETED_FALSE )
                .orderByAsc(Contacts::getLevel);
        List<Contacts> contactsList = contactsService.list( contactsWrapper );
        List<ContactsResponse> contactsResponseList = BeanConvertUtils.convertListTo( contactsList, ContactsResponse::new );
        //级别名称
        for (ContactsResponse contactsResponse : contactsResponseList) {
            if (contactsResponse.getLevel() != null) {
                DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                        Constants.CONTACT_LEVEL).stream().filter(a->a.getValue().equals(
                        contactsResponse.getLevel().toString())).collect(Collectors.toList()).get(0);
                contactsResponse.setLevelName(communicationModeDict.getName());
            }
        }
        consumerH5Response.setContactsResponseList(contactsResponseList);
        //获取订单信息
        QueryWrapper<DtuBindingOrder> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.lambda().or().eq(DtuBindingOrder::getIsDeleted,0)
                .eq(DtuBindingOrder::getConsumerId,id);
        List<DtuBindingOrder> dtuBindingOrders = dtuBindingOrderMapper.selectList(objectQueryWrapper);
        if (!CollectionUtil.isEmpty(dtuBindingOrders)) {
            DtuBindingOrder dtuBindingOrder = dtuBindingOrders.get(0);
            consumerH5Response.setType(2);
            consumerH5Response.setOrderAddress(dtuBindingOrder.getAddress());
            consumerH5Response.setOrderCustName(dtuBindingOrder.getCustName());
            consumerH5Response.setOrderPhone(dtuBindingOrder.getPhone());
        }else{
            consumerH5Response.setType(1);
        }
        List<String> query = equipmentService.getQueryParams();
        List<Map<String, String>> customerCode = equipmentService.dictMap(null, query, consumerH5Response.getSpId());
        consumerH5Response.setIndustryType(equipmentService.getStringValue(customerCode,
                consumerH5Response.getIndustryType(), query.get(5), "value", "alias"));
        return consumerH5Response;
    }

    @Override
    public StrategyReportResponse report(@Valid ReportRequest request) {
        log.info("report-param:{}",JSONObject.toJSONString(request));
        StrategyReportResponse strategyReportResponse = new StrategyReportResponse();
        QueryWrapper<Dtu> dtuWrapper = new QueryWrapper<>();
        dtuWrapper.lambda().like(Dtu::getIMEI, request.getImei());
        List<Dtu> dtus = dtuMapper.selectList(dtuWrapper);
        log.info("report-dtus:{}",JSONObject.toJSONString(dtus));
        if (CollectionUtils.isEmpty(dtus)){
            throw new BizException("imei不存在");
        }
        String date = StringUtils.isEmpty(request.getReportDate()) ? DateUtil.format(DateUtil.offsetMonth(new Date(), -1), "yyyy-MM") : request.getReportDate();
        QueryWrapper<RunningReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RunningReport::getIsDeleted,0)
                .eq(RunningReport::getConsumerId,dtus.get(0).getConsumerId())
                .eq(RunningReport::getReportDate,date);
        RunningReport report = runningReportMapper.selectOne(queryWrapper);
        log.info("report-report:{}",JSONObject.toJSONString(report));
        if (report == null ) {
            strategyReportResponse.setStatus(0); // 无报告
            return strategyReportResponse;
        }
        if (report.getCheckStatus() == 0 && request.getIsForTrial() == 0) {
            strategyReportResponse.setStatus(1); // 报告正在生成中
            return strategyReportResponse;
        }
        strategyReportResponse.setStatus(2); // 报告已生成
        strategyReportResponse.setImei(request.getImei());
        strategyReportResponse.setReportDate(date);
        strategyReportResponse.setConsumerId(dtus.get(0).getConsumerId());
        // 服务到期状态
        QueryWrapper<ConsumerServiceInfo> serviceInfoWrapper = new QueryWrapper<>();
        serviceInfoWrapper.lambda().eq(ConsumerServiceInfo::getSpId, dtus.get(0).getSpId())
                .eq(ConsumerServiceInfo::getIsDeleted, 0)
                .eq(ConsumerServiceInfo::getImei, request.getImei());
        List<ConsumerServiceInfo> consumerServiceInfoList = consumerServiceInfoMapper.selectList(serviceInfoWrapper);
        Long today = DateUtils.today().getTime();
        if (CollectionUtil.isNotEmpty(consumerServiceInfoList)) {
            ConsumerServiceInfo serviceInfo = consumerServiceInfoList.get(0);
            if (today <= serviceInfo.getEndDate().getTime() && serviceInfo.getEndDate().getTime() - today <= 30*24*60*60*1000L) {
                strategyReportResponse.setServiceStatus(1);
            } else if (today > serviceInfo.getEndDate().getTime()) {
                strategyReportResponse.setServiceStatus(2);
            } else {
                strategyReportResponse.setServiceStatus(0);
            }
        }

        Integer alarmNumber = 0;
        Integer alarmUnprocessedNumber = 0;
        Integer brokenNumber = 0;
        Integer brokenUnprocessedNumber = 0;
        Long offlineTime = 0L;  // 离线时长，单位为秒
        // 报警故障列表
        QueryWrapper<RunningReportData> runningReportDataQueryWrapper = new QueryWrapper<>();
        runningReportDataQueryWrapper.lambda().eq(RunningReportData::getSpId, dtus.get(0).getSpId())
                .eq(RunningReportData::getIsDeleted, 0)
                .like(RunningReportData::getImei, request.getImei())
                .eq(RunningReportData::getReportId, report.getId());
        List<RunningReportData> runningReportDataList = runningReportDataMapper.selectList(runningReportDataQueryWrapper);
        if (!CollectionUtils.isEmpty(runningReportDataList)) {
            List<H5LogRes> resultList = new ArrayList<>();
            for (RunningReportData data : runningReportDataList) {
                if (data.getAlarmType() == 0) {
                    alarmNumber ++ ;
                    if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                            data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                        alarmUnprocessedNumber ++ ;
                    }
                }else if (data.getAlarmType() == 1) {
                    brokenNumber ++ ;
                    if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                            data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                        brokenUnprocessedNumber ++ ;
                    }
                }else if (data.getAlarmType() == 2) {
                    // 离线
                    offlineTime = offlineTime + data.getOfflineTime();
                }
                H5LogRes res = new H5LogRes();
                res.setImei(data.getImei());
                res.setEventTime(data.getAlarmTime());
                res.setEventType(data.getAlarmType());
                res.setEventInfo(data.getValveBrokenInfo());
//                res.setEventInfo("泄漏报警");
                if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                        data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                    res.setStatus(0);
                } else {
                    res.setStatus(1);
                }
                resultList.add(res);
            }
            strategyReportResponse.setAlarmBorkenList(resultList);
        }
        strategyReportResponse.setAlarmNumber(alarmNumber);
        strategyReportResponse.setAlarmUnprocessedNumber(alarmUnprocessedNumber);
        if (strategyReportResponse.getAlarmUnprocessedNumber() > 0) {
            strategyReportResponse.setAlarmHandleStatus(1); // 存在未处理
        } else {
            strategyReportResponse.setAlarmHandleStatus(0); // 全部已处理
        }
        strategyReportResponse.setBrokenNumber(brokenNumber);
        strategyReportResponse.setBrokenUnprocessedNumber(brokenUnprocessedNumber);
        if (strategyReportResponse.getBrokenUnprocessedNumber() > 0) {
            strategyReportResponse.setBrokenHandleStatus(1); // 存在未处理
        } else {
            strategyReportResponse.setBrokenHandleStatus(0); // 全部已处理
        }
        strategyReportResponse.setOfflineTime(offlineTime);
        strategyReportResponse.setOfflineTimeStr(TimeUtil.secondToStr(offlineTime));
        return strategyReportResponse;
    }

    @Override
    public Map<String,Object> reportAmount(String subsCode) {
        Map<String, Object> map = new HashMap<>();
        List<String> list=reportMapper.selectCountBySubsCode(subsCode);
        map.put("count",CollectionUtils.isEmpty(list)?0:list.size());
        map.put("imei",list.size()==1?list.get(0):"");
        return map;
    }


}